package hasthi.tools;

import static hasthi.common.constants.WSDMConstants.GROUP_PARAM;
import static hasthi.common.constants.WSDMConstants.RESOURCE_CATEGORY_PARAM;
import static hasthi.common.constants.WSDMConstants.RESOURCE_NAME_PARAM;
import static hasthi.common.constants.WSDMConstants.RESOURCE_STATUS_PARAM;
import static hasthi.common.constants.WSDMConstants.RESOURCE_TYPE_PARAM;
import static hasthi.wsdm.capabilities.MetricsCapability.FALIED_REQUESTS;
import static hasthi.wsdm.capabilities.MetricsCapability.LAST_REQUEST_RECIVED_TIME;
import static hasthi.wsdm.capabilities.MetricsCapability.NUMBER_OF_SUCCESSFUL_REQUESTS;
import static hasthi.wsdm.capabilities.MetricsCapability.PENDING_REQUESTS;
import hasthi.actuators.ActionCenter;
import hasthi.actuators.ActionContext;
import hasthi.actuators.ManagementAction;
import hasthi.actuators.SystemActionsScheduler;
import hasthi.common.BaseContext;
import hasthi.common.ComponetFactory;
import hasthi.common.HasthiException;
import hasthi.common.InvaliedResourceDataException;
import hasthi.common.SafeScheduler;
import hasthi.common.Utils;
import hasthi.common.HasthiException.FaultCode;
import hasthi.common.constants.HasthiConstants;
import hasthi.common.constants.WSDMConstants;
import hasthi.common.constants.WSDMConstants.SystemState;
import hasthi.decision.RuleEngine;
import hasthi.metamodel.ChangeBuffer;
import hasthi.metamodel.MixedResourceModel;
import hasthi.metamodel.resource.EditableManagedResource;
import hasthi.metamodel.resource.ManagedResource;
import hasthi.metamodel.resource.ResourceModelContext;
import hasthi.metamodel.resource.ManagedResource.ResourceType;
import hasthi.tools.analyze.RulePerfSuite.DummyActionCenter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.drools.commons.jci.stores.ResourceStore;
import org.mvel.MVEL;

public class TestingUtils {
    private Map<QName,Object> reusedHashMap = new HashMap<QName, Object>();
    private int count = 0;
    private  Random random = new Random();
    private  ChangeBuffer listener = new ChangeBuffer();
    private  List<String> hosts = new ArrayList<String>();
    private  ResourceModelContext modelContext = new ResourceModelContext(null,null,null,new ChangeBuffer());
    private MixedResourceModel mixedResourceModel;
    private boolean createNewResource = false;
    private static Log log = LogFactory.getLog(HasthiConstants.LOGGER_NAME);
    //boolean temp = false;
    private long failureCount = 0;
    
    public static String[] PERSISTANT_SERVIES = new String[]{"WorkflowEngine","Xregistry","DSC","FTR","SCMS",
        "MessageBroker","MyleadAgent","MyleadServer","Factory","AuditingService","DataCatalog","DAMN","MessageBox"};
    public static String[] APP_SERVICES = new String[]{"WRF","ADAS","NAM","WRFStatic","Cluster"};
    private BaseContext baseContext;
    
    public TestingUtils(BaseContext baseContext) throws HasthiException{
        this.baseContext = baseContext;
        mixedResourceModel = new MixedResourceModel(modelContext);
    }
    
    public  EditableManagedResource createRandomResource(ResourceType category,QName type,String group) throws InvaliedResourceDataException, HasthiException{
        return createRandomResource(category, type,group, new String[][]{});
    }

    public  EditableManagedResource createRandomResource(ResourceType category,QName type,String group,String[]... params) throws InvaliedResourceDataException, HasthiException{
        return createRandomResource(category, type,"http://dummyurl/dummy",group, params);
    }
    
    public int ranInt(int i){
        return Math.abs(random.nextInt(i));
    }
    
    public int nextGaussian(int i){
        return (int)Math.abs(random.nextGaussian()*i);
    }
    
    public  EditableManagedResource createRandomResource(ResourceType category,QName type,
            String managmentAgentURL,String group,String[]... params) throws InvaliedResourceDataException, HasthiException{
        return createRandomResource(null,category,type,managmentAgentURL,group,params);
    }
    public  synchronized EditableManagedResource createRandomResource(QName name,ResourceType category,QName type,
            String managmentAgentURL,String group,String[]... params) throws InvaliedResourceDataException, HasthiException{
        count++;
        reusedHashMap.clear();

        long now = System.currentTimeMillis();
        if(category == null){
            double decider = random.nextDouble();
            if(decider > 0.8){
                category = ResourceType.Host;
            }else if(decider > 0.9){
                category = ResourceType.ComputeNode;
//            }else if(decider > 0.6){
//                category = ResourceType.Service;
            }else{    
                category =  ResourceType.TransientService; 
            }
        }
        if(category.equals(ResourceType.TransientService) || category.equals(ResourceType.Service)){
            if(name == null){
                name = new QName(type.getNamespaceURI(),type.getLocalPart() + count);    
            }
            reusedHashMap.put(RESOURCE_TYPE_PARAM, type.toString());
        }else{
            name = type;
        }
        
        
        reusedHashMap.put(new QName(GROUP_PARAM.getLocalPart()), group);
        reusedHashMap.put(new QName("lastUpdated"), now);
        switch(category){
            case Service:case TransientService:
                if(createNewResource){
                    reusedHashMap.put(LAST_REQUEST_RECIVED_TIME, 0);
                    reusedHashMap.put(PENDING_REQUESTS, 0);
                    reusedHashMap.put(FALIED_REQUESTS, 0);
                    reusedHashMap.put(NUMBER_OF_SUCCESSFUL_REQUESTS, 0);
                }else{
                    reusedHashMap.put(LAST_REQUEST_RECIVED_TIME, now - ranInt(10000));
                    reusedHashMap.put(PENDING_REQUESTS, ranInt(5));
                    reusedHashMap.put(FALIED_REQUESTS, (int)(nextGaussian(10)));
                    reusedHashMap.put(NUMBER_OF_SUCCESSFUL_REQUESTS, (int)(nextGaussian(100)));
                }
                break;
            case Host:
                //reusedHashMap.put(new QName("numberOfServices"), ranInt(25));
                reusedHashMap.put(new QName("cpuUsage"), ranInt(100));
                reusedHashMap.put(new QName("harddiskUsage"), ranInt(100));
                hosts.add(name.getLocalPart());
                break;
        }
        
        
        reusedHashMap.put(RESOURCE_CATEGORY_PARAM, category.toString());
        reusedHashMap.put(RESOURCE_NAME_PARAM, name.getNamespaceURI()+"/"+name.getLocalPart());
        int hostSize = hosts.size();
        if(hostSize > 0){
            int index = Math.abs(ranInt(100))%hostSize;
            reusedHashMap.put(WSDMConstants.HOSTNAME_PARAM,hosts.get(index));
        }else{
            reusedHashMap.put(WSDMConstants.HOSTNAME_PARAM,Utils.getLocalHost());
        }
        double randomVal = Math.abs(random.nextGaussian());
        if(createNewResource){
            reusedHashMap.put(RESOURCE_STATUS_PARAM, SystemState.IdleState.toString());
        }else if(randomVal < 0.0003f){
            reusedHashMap.put(RESOURCE_STATUS_PARAM, SystemState.CrashedState.toString());
        }else if(randomVal > 0.3 && randomVal < 0.5){
            reusedHashMap.put(RESOURCE_STATUS_PARAM, SystemState.BusyState.toString());
        }else if(randomVal > 0.95){
            reusedHashMap.put(RESOURCE_STATUS_PARAM, SystemState.SaturatedState.toString());
        }else{
            reusedHashMap.put(RESOURCE_STATUS_PARAM, SystemState.IdleState.toString());
        }
        if(params != null){
            for(String[] paramset:params){
                reusedHashMap.put(new QName(paramset[0]),paramset[1]);
            }
        }
        return mixedResourceModel.createNewResource(reusedHashMap,managmentAgentURL);
        
    }
    /*
    public  boolean performChange4Coordinator1(EditableManagedResource resource,float failureProb) throws HasthiException{
        boolean failed = false;
        ResourceType category = ResourceType.valueOf(resource.getCategory());
        switch(category){
            case Service:case TransientService:
                int newReqCount = nextGaussian(10);
                int requestFalied = 0;
                int requestSucessful = 0;
                long lastRequestReceived = System.currentTimeMillis() - nextGaussian(10);


                for(int i =0;i<newReqCount;i++){
                    if(Utils.selectWithProbability(0.1f)){
                        requestFalied++;
                    }else{
                        requestSucessful++;
                    }

//                    lastRequestProcessingTime = (long)Math.abs(random.nextGaussian()) + 10;
//                    if(lastRequestProcessingTime > maxRequestTime){
//                        maxRequestTime = lastRequestProcessingTime;
//                    }
                }
                int newPendingrequests = newReqCount - requestFalied - requestSucessful
                    +(random.nextBoolean()?+1:-1)*ranInt(5);
                resource.setProperty(LAST_REQUEST_RECIVED_TIME.getLocalPart(),
                        String.valueOf(lastRequestReceived));
                doUpdate(resource, PENDING_REQUESTS, newPendingrequests);
                doUpdate(resource, FALIED_REQUESTS, requestFalied);
                doUpdate(resource, NUMBER_OF_SUCCESSFUL_REQUESTS, requestSucessful);
                break;
            case Host:
                doUpdate(resource, new QName("cpuUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                doUpdate(resource, new QName("harddiskUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                break;
        }

        if(Utils.selectWithProbability(failureProb/120f)){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.CrashedState.toString());
            log.info("ServiceDied: "+resource.getName() + " "+ failureCount);
            failed = true;
            failureCount++;
        }else{
            if(category == ResourceType.Service || category == ResourceType.TransientService){
                if(!resource.getState().equals(SystemState.SaturatedState.toString())){
                    int pendingRequests = Integer.parseInt(resource.getProperty(PENDING_REQUESTS.getLocalPart()));
                    if(pendingRequests > 200){
                        resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.SaturatedState.toString());
                        resource.setProperty(PENDING_REQUESTS.getLocalPart(), "101");
                    }
                }else if(!resource.getState().equals(SystemState.BusyState.toString())){
                    int pendingRequests = Integer.parseInt(resource.getProperty(PENDING_REQUESTS.getLocalPart()));
                    if(pendingRequests > 1){
                        resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.BusyState.toString());
                    }
                }
            }
        }
        return failed;
    }
         */           

    public  boolean performChange4Coordinator(EditableManagedResource resource,float failureProb) throws HasthiException{
        float propto30epoch = baseContext.getManagerEpochSeconds()/30f; 
        //float propto30epoch = 1;
        boolean failed = false;
        ResourceType category = ResourceType.valueOf(resource.getCategory());
        switch(category){
            case Service:case TransientService:
                int newReqCount = nextGaussian(Math.round(10*propto30epoch));
                int requestFalied = 0;
                int requestSucessful = 0;
                long lastRequestReceived = System.currentTimeMillis() - nextGaussian(10);
               
                    
                for(int i =0;i<newReqCount;i++){
                    if(Utils.selectWithProbability(0.1f)){
                        requestFalied++;
                    }else{
                        requestSucessful++;
                    }
                    
//                    lastRequestProcessingTime = (long)Math.abs(random.nextGaussian()) + 10;
//                    if(lastRequestProcessingTime > maxRequestTime){
//                        maxRequestTime = lastRequestProcessingTime;
//                    }
                }
                int newPendingrequests = newReqCount - requestFalied - requestSucessful 
                    +(random.nextBoolean()?+1:-1)*ranInt(Math.round(5*propto30epoch));
//                if(Utils.selectWithProbability(propto30epoch*0.00001f)){
                if(Utils.selectWithProbability((double)0.01*propto30epoch/120)){
                    newPendingrequests = newPendingrequests+200;
                }                
                
                resource.setProperty(LAST_REQUEST_RECIVED_TIME.getLocalPart(), 
                        String.valueOf(lastRequestReceived));
                
                
                doUpdate(resource, PENDING_REQUESTS, newPendingrequests);
                doUpdate(resource, FALIED_REQUESTS, requestFalied);
                doUpdate(resource, NUMBER_OF_SUCCESSFUL_REQUESTS, requestSucessful);
                break;
            case Host:
                doUpdate(resource, new QName("cpuUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                doUpdate(resource, new QName("harddiskUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                break;
        }
        
        if(Utils.selectWithProbability(failureProb*propto30epoch/120f)){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.CrashedState.toString());
            log.info("ServiceDied: "+resource.getName() + " "+ failureCount);
            failed = true;
            failureCount++;
            System.out.println("using "+ propto30epoch);
        }else{
            if(category == ResourceType.Service || category == ResourceType.TransientService){
                if(!resource.getState().equals(SystemState.SaturatedState.toString())){
                    int pendingRequests = Integer.parseInt(resource.getProperty(PENDING_REQUESTS.getLocalPart()));
                    if(pendingRequests > 200){
                        resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.SaturatedState.toString());
                        resource.setProperty(PENDING_REQUESTS.getLocalPart(), "101");
                        log.info("ServiceSaturated: "+resource.getName() + " ");
                    }
                }else if(!resource.getState().equals(SystemState.BusyState.toString())){
                    int pendingRequests = Integer.parseInt(resource.getProperty(PENDING_REQUESTS.getLocalPart()));
                    if(pendingRequests > 10){
                        resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.BusyState.toString());
                    }
                }
            }
        } 
        return failed;
    }

    
    public  void performChange(EditableManagedResource resource) throws HasthiException{
        ResourceType category = ResourceType.valueOf(resource.getCategory());
        switch(category){
            case Service:case TransientService:
                int newReqCount = nextGaussian(10);
                int requestFalied = 0;
                int requestSucessful = 0;
                long lastRequestReceived = System.currentTimeMillis() - nextGaussian(10);
                //long lastRequestProcessingTime = resource.getProperty(name)
                    
                for(int i =0;i<newReqCount;i++){
                    if(Utils.selectWithProbability(0.1f)){
                        requestFalied++;
                    }else{
                        requestSucessful++;
                    }
                    
//                    lastRequestProcessingTime = (long)Math.abs(r.nextGaussian()) + 10;
//                    if(lastRequestProcessingTime > maxRequestTime){
//                        maxRequestTime = lastRequestProcessingTime;
//                    }
                }
                resource.setProperty(LAST_REQUEST_RECIVED_TIME.getLocalPart(), 
                        String.valueOf(lastRequestReceived));
                doUpdate(resource, PENDING_REQUESTS, (newReqCount - requestFalied - requestSucessful) 
                        +(random.nextBoolean()?+1:-1)*ranInt(5));
                doUpdate(resource, FALIED_REQUESTS, requestFalied);
                doUpdate(resource, NUMBER_OF_SUCCESSFUL_REQUESTS, requestSucessful);
                break;
            case Host:
                doUpdate(resource, new QName("cpuUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                doUpdate(resource, new QName("harddiskUsage"), (random.nextBoolean()?+1:-1)*ranInt(5));
                break;
        }
        double randomVal = Math.abs(random.nextGaussian());
//        if(!temp && resource.getName().contains("Xreg")){
//            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.CrashedState.toString());
//            log.info("Shutdown "+resource.getName());
//            temp = true;
//        }
        if(category == ResourceType.Service && Utils.selectWithProbability(0.0008f)){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.CrashedState.toString());
            log.info("Shutdown "+resource.getName());
        }else if(Utils.selectWithProbability(0.00003f)){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.CrashedState.toString());
            log.info("Shutdown "+resource.getName());
        }else if(randomVal < 0.5){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.IdleState.toString());    
        }else if(randomVal > 0.5 && randomVal < 0.8){
            resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.BusyState.toString());
        }
        
        if(category == ResourceType.Service || category == ResourceType.TransientService){
            int pendingRequests = Integer.parseInt(resource.getProperty(PENDING_REQUESTS.getLocalPart())); 
            if(pendingRequests > 200){
                resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.SaturatedState.toString());
                resource.setProperty(PENDING_REQUESTS.getLocalPart(), "101");
            }
        }else{
            if(Utils.selectWithProbability(0.005f)){
                resource.setProperty(RESOURCE_STATUS_PARAM.getLocalPart(), SystemState.SaturatedState.toString());
            }
        }
    }
    
    
    public void doUpdate(ManagedResource resource,QName propertyName,int delta) throws NumberFormatException, HasthiException{
        Long oldval = Long.valueOf(resource.getProperty(propertyName.getLocalPart()));
        long val = oldval + delta;
        ((EditableManagedResource)resource).setProperty(propertyName.getLocalPart(), val > 0?val:0);
    }
    
    public  List<ManagedResource> createResourceSet(int groupCount) throws InvaliedResourceDataException, HasthiException{
        List<ManagedResource> resoureces = new ArrayList<ManagedResource>();
        
        for(int i = 0;i<groupCount;i++){
            for(String name:PERSISTANT_SERVIES){
                resoureces.add(createRandomResource(ResourceType.Service, 
                        new QName("http://extreme.indiana.edu/dummyservice/",name),String.valueOf(groupCount)));
            }

        }
        return resoureces;
    }
    
    public void clearChangeBuffer(){
        listener.reset();
    }

    public MixedResourceModel getMixedResourceModel() {
        return mixedResourceModel;
    }
    
    public void addHost(String host){
        hosts.add(host);
    }

    public void setCreateNewResource(boolean createNewResource) {
        this.createNewResource = createNewResource;
    }
    
    public static Properties getTestingProperties() throws HasthiException{
        try {
            Properties properties = new Properties();
            String property = System.getProperty("hasthi.testConig");
            FileInputStream in = null;
            if(property != null){
                in  = new FileInputStream(property);
            }else{
                File file = new File("hasthi_test.properties"); 
                if(file.exists()){
                    in  = new FileInputStream(file);
                }
            }
            if(in != null){
                properties.load(in);
                in.close();
            }
            return properties;
        } catch (FileNotFoundException e) {
            throw new HasthiException(e,FaultCode.InitalizationError);
        } catch (IOException e) {
            throw new HasthiException(e,FaultCode.InitalizationError);
        }
    }
    
    
    //private static Pattern RESOURCE_TEST_SPEC_PATTERN = Pattern.compile("(^[,#]*?)#(^[,\\[]*?)\\[(.*?)\\]");
    private static Pattern RESOURCE_TEST_SPEC_PATTERN = Pattern.compile("([^,]*?)#(.*?)\\[(.*?)\\]");
    private static Pattern REPEAT_RESOURCE_PATTERN = Pattern.compile("__([0-9]+)X_(.*)");
    
    public List<ManagedResource> parseResources(String resSpec) throws InvaliedResourceDataException, HasthiException{
        List<ManagedResource> resources = new ArrayList<ManagedResource>();
        Matcher m =  RESOURCE_TEST_SPEC_PATTERN.matcher(resSpec);
        while(m.find()){
            String resourceType = m.group(1).trim();
            String type = m.group(2).trim();
            
            int count = 1;
            
            if(resourceType.startsWith("__")){
                Matcher m2 = REPEAT_RESOURCE_PATTERN.matcher(resourceType);
                if(m2.matches()){
                    resourceType = m2.group(2);
                    count = Integer.parseInt(m2.group(1));
                }else{
                    throw new HasthiException("Illformatted resource type "+ resourceType,FaultCode.InvaliedLocalArgumnet);
                }
            }
            
            for(int i=0;i<count;i++){
                EditableManagedResource resource;
                if(type.endsWith("__SAME__")){
                    type = type.replace("__SAME__", "");
                    resource = createRandomResource(QName.valueOf(type),ResourceType.valueOf(resourceType), QName.valueOf(type),"http://linbox3:0", "0") ;
                }else{
                    resource = createRandomResource(ResourceType.valueOf(resourceType), QName.valueOf(type), "0") ;
                }
                resources.add(resource);
                if(m.groupCount() > 2){
                    String paramsSpec = m.group(3);
                    String[] paramsData = paramsSpec.split("\\s");
                    if(paramsData != null){
                        for(String paramData:paramsData){
                            String[] vals = paramData.split("=");
                            if(vals.length != 2){
                                throw new HasthiException("Illformatted parameter "+ paramData,FaultCode.InvaliedLocalArgumnet);
                            }
                            if(vals[0].equals("active")){
                                resource.setActive(Boolean.parseBoolean(vals[1]));
                            }else{
                                resource.setProperty(vals[0], vals[1]);    
                            }
                        }
                    }
                    
                    
                    
                }
            }
        }
        return resources;
    }
    
    public void testRulesViaTestSpec(String testspecAsStr,String ruleFile) throws HasthiException, InvaliedResourceDataException{
        DummyActionCenter dummyActionCenter = new DummyActionCenter();
        RuleEngine engine = createActiveEngine(ruleFile, dummyActionCenter);
        List<ManagementAction> actions = dummyActionCenter.getActions();
        
        String[] testData = testspecAsStr.split("\\|");
        
        if(testData.length != 2){
            throw new HasthiException("Wrong Format, Should be Resources|actions "+ testspecAsStr,FaultCode.InvaliedLocalArgumnet);
        }
        
        //Handle global parameters
        if(testData[0].startsWith("Global")){
            int index = testData[0].indexOf("]");
            String global = testData[0].substring(0,index);
            global = global.substring(global.indexOf("[")+1);
            String[] nameValuePairs = global.split("\\s");
            
            for(String pair:nameValuePairs){
                String[] pairdata = pair.split("=");
                if(pairdata.length != 2){
                    throw new HasthiException("Illformattered global data"+ pair, FaultCode.InvaliedLocalArgumnet);
                }
                Object val = pairdata[1];
                if(pairdata[1].endsWith("___l")){
                    val = new Long(Long.parseLong(pairdata[1].replaceAll("___l", "")));
                }
                
                dummyActionCenter.put(pairdata[0], val);
            }
            
            testData[0] = testData[0].substring(index+1);
        }
        
        

        List<ManagedResource> templateResources = parseResources(testData[0]);
        for (ManagedResource resourceTemplate : templateResources) {
            engine.addObject(resourceTemplate);
            System.out.println(resourceTemplate);
        }
        engine.fire();
        
        if(testData[1].startsWith("Global")){
            int index = testData[1].indexOf("]");
            String global = testData[1].substring(0,index);
            global = global.substring(global.indexOf("[")+1);
            String[] nameValuePairs = global.split(",");
            
            
            
            
            for(String pair:nameValuePairs){
                HashMap map = new HashMap();
                map.put("map", dummyActionCenter.getMap());
                Boolean bool = (Boolean)MVEL.eval(pair,map);
                if(!bool){
                    throw new HasthiException("expression "+ pair + " failed with "+ dummyActionCenter.getMap(), FaultCode.LocalError);
                }
                
//                String[] pairdata = pair.split("=");
//                if(pairdata.length != 2){
//                    throw new HasthiException("Illformattered global data"+ pair, FaultCode.InvaliedLocalArgumnet);
//                }
//                if(!pairdata[1].equals(dummyActionCenter.get(pairdata[0]))){
//                    throw new HasthiException("Expected global value "+ pairdata[1]  + "for "+ pairdata[0] 
//                         + " but found "+ dummyActionCenter.get(pairdata[0]), FaultCode.LocalError);
//                }
            }
            testData[1] = testData[1].substring(index+1);
        }
        
        
        String[] actionStrs = testData[1].split(",");
        
        
        System.out.println("LIST="+actions);
        for(String actionStr:actionStrs){
            actionStr = actionStr.replace("@", "|").trim();
            ManagementAction matchingAction = null;
            for(ManagementAction action:actions){
                if(action.getActionID().contains(actionStr)){
                    matchingAction = action;
                    break;
                }
            }
            if(matchingAction == null){
                throw new HasthiException("action "+ actionStr + " not found in "+ actions,FaultCode.LocalError);
            }else{
                actions.remove(matchingAction);
            }
        }
        
        Iterator<ManagementAction> it = actions.iterator();
        while(it.hasNext()){
            if(it.next().getActionID().contains("SystemStartAction")){
                it.remove();
            }
        }
        
        if(actions.size() > 0){
            throw new HasthiException("Unexpcected Action found ="+ actions,FaultCode.ConfigError);
        }
    }
    
    
    public RuleEngine createActiveEngine(String rulefile, ActionCenter actionCenter) throws HasthiException {
        BaseContext baseContext = new BaseContext();
        ActionContext actionContext = new ActionContext(baseContext, false);
        actionContext.setScheduler(new SafeScheduler(2,new SafeScheduler.JobCancelledCallback() {
            public void jobCancelled(Runnable runnable) {
                System.out.println("Canceled");
            }
        
        },true));
        actionContext.setResourceModel(getMixedResourceModel());
        actionContext.setUnicastContainer(ComponetFactory.createSoapContianier(baseContext, null));

        actionCenter.init(actionContext);
        RuleEngine engine = new RuleEngine(rulefile, actionCenter);
        actionContext.setRuleEngine(engine);
        return engine;
    }

    public long getFailureCount() {
        return failureCount;
    }
    
}
